home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / keyb / autokey.zip / AUTOKEY.ASM next >
Assembly Source File  |  1989-01-24  |  14KB  |  554 lines

  1. comment |
  2.    This program reads a file of keystrokes into a buffer and uses them 
  3.    to replace keyboard input until the buffer is empty.
  4.  
  5.    Written for MASM 5.1 (should compile with earlier versions)
  6.    Save as AUTOKEY.ASM
  7.    Compile:  MASM AUTOKEY;
  8.             LINK AUTOKEY; (ignore stack segment warning)
  9.          EXE2BIN AUTOKEY.EXE AUTOKEY.COM   
  10.        |
  11.  
  12. CR    equ    0dh            ;Definitions for
  13. LF    equ    0ah            ;  the program's use
  14. TAB    equ    09h
  15.     
  16. code_seg segment
  17.     assume cs:code_seg, ds:code_seg, es:code_seg
  18.  
  19.     org    100h            ;.COM file format
  20.  
  21. start:    jmp    begin
  22.  
  23. ;---------
  24. ;  Data used by the 
  25. ;  memory-resident portion of
  26. ;  the program.
  27. ;---------
  28.  
  29. kbd_head    equ    1ah
  30. kbd_tail    equ    1ch
  31. kbd_start    equ    80h
  32. kbd_end        equ    82h
  33.  
  34. int8_gate    db    ?
  35.  
  36. old_08        dd    ?
  37. old_09        dd    ?
  38. save_ss        dw    ?
  39. save_sp        dw    ?
  40.         dw    50h dup (?)
  41. our_stack    equ    $-2
  42.  
  43. buf_ptr        dw    offset keybuf
  44. buf_count    dw    0
  45.  
  46. BUF_SIZE    equ    500         ;Change to suit your needs
  47. keybuf        db    BUF_SIZE dup (?)
  48.  
  49. ;---------
  50. ;  Keyboard Interrupt 09 hex
  51. ;  While keys are being sent 
  52. ;  to the buffer from Autokey,
  53. ;  disable the physical keyboard
  54. ;  by simply ignoring all keystrokes
  55. ;---------
  56.  
  57. new_int09    proc    far
  58.     test    cs:buf_count,-1         ;Are we sending keystrokes?
  59.     jz    orig_int9         ;No -- go
  60.     push    ax             ;Else save AX
  61.     in    al,60h             ;Read the keystroke
  62.     in    al,61h             ;Get Port B value
  63.     or    al,80h             ;Set high bit
  64.     out    61h,al             ;Send it out
  65.     and    al,7fh             ;Clear high bit
  66.     out    61h,al             ;We said we received it
  67.     mov    al,20h             ;Signal end of
  68.     out    20h,al             ;  hardware interrupt
  69.     pop    ax             ;Recover original AX
  70.     iret                 ;Key is swallowed
  71. orig_int9:
  72.     jmp    dword ptr cs:[old_09]     ;Use original code for Int 9
  73. new_int09    endp
  74.  
  75. ;---------
  76. ;  Timer Interrupt
  77. ;  This is where we stuff the
  78. ;  keyboard buffer
  79. ;---------
  80.  
  81. new_int08    proc    far
  82.     pushf                 ;Simulate an interrupt call
  83.     call    dword ptr cs:[old_08]     ;Hand off to previous code
  84.     test    cs:buf_count,-1          ;Anything to stuff
  85.     jz    new8_out         ;No -- leave immediately
  86.     test    cs:int8_gate,-1         ;Okay to execute?
  87.     jz    stuff_keys
  88. new8_out:
  89.     iret                 ;Return to interrupted program    
  90.  
  91. stuff_keys:
  92. ;------
  93. ;  Set the gate flag.
  94. ;  switch stacks, and save
  95. ;  necessary registers.
  96. ;------
  97.     mov    cs:int8_gate,-1         ;Don't allow recursive calls
  98.     push    ax             ;Save caller's AX
  99.     mov    cs:[save_ss],ss         ;Save caller's stack
  100.     mov    cs:[save_sp],sp
  101.     cli                 ;Interrupts off to switch stack
  102.     mov    ax,cs             ;Get our segment
  103.     mov    ss,ax             ;  in SS
  104.     mov    sp,offset our_stack     ;Move to our stack
  105.     and    sp,0fffeh         ;Make sure it's even
  106.     sti                 ;Interrupts on now
  107.     push    ds             ;Save caller's segments
  108.     push    es
  109.     mov    ds,ax             ;Point to our segment
  110.     push    di             ;Now save registers we need
  111.     push    si
  112.     push    bx
  113.     mov    ax,40h             ;Segment for BIOS buffer
  114.     mov    es,ax             ;ES ==> BIOS segment
  115.     mov    di,es:[kbd_head]     ;Get head of buffer
  116.     mov    bx,es:[kbd_tail]     ;  and the tail
  117.     cmp    di,bx             ;Is buffer empty?
  118.     jne    end_stuff         ;No -- forget it
  119.     mov    si,[buf_ptr]         ;DS:SI ==> head of our buffer
  120.     lodsw                 ;Get next word
  121.     mov    [buf_ptr],si         ;Save new pointer
  122.     dec    [buf_count]         ;Count this keystroke
  123.     or    ax,ax             ;Is keystroke null?
  124.     jz    end_stuff         ;Yes -- don't stuff it
  125.     stosw                 ;Else put it in buffer
  126.     inc    bx             ;Move tail pointer
  127.     inc    bx
  128.     cmp    bx,es:[kbd_end]         ;Past the end?
  129.     jl    dont_wrap         ;No -- go
  130.     mov    bx,es:[kbd_start]     ;Get start of key buffer
  131. dont_wrap:
  132.     mov    es:[kbd_tail],bx     ;Save new value
  133. end_stuff:
  134.     pop    bx             ;Clear our stack
  135.     pop    si
  136.     pop    di
  137.     pop    es
  138.     pop    ds
  139.     cli                 ;Interrupts off to
  140.     mov    ss,cs:[save_ss]         ;  switch stacks
  141.     mov    sp,cs:[save_sp]
  142.     pop    ax             ;All done
  143.     mov    cs:int8_gate,0         ;Let next call in
  144.     jmp    new8_out         ;And leave
  145. new_int08    endp
  146.  
  147. res_code    equ    $ - new_int08
  148.  
  149. res_size    equ    $-start
  150.  
  151. ;---------
  152. ;  Installation code
  153. ;  and file parsing.
  154. ;  Everything from here to the end
  155. ;  is discarded when the TSR is installed
  156. ;---------
  157.  
  158. ;---------
  159. ;  Transient Data
  160. ;---------
  161.  
  162. temp_buf    db    BUF_SIZE * 2 dup (0)
  163.  
  164. hello        db    CR,"AUTOKEY Automatic Keyboard Entry",CR,LF,"$"
  165. bad_ver        db    "This program requires DOS 2.0 or later",CR,LF,"$"
  166. no_file        db    "Usage: AUTOKEY keyfile",CR,LF,"$"
  167. no_open        db    "Cannot open keystroke file",CR,LF,"$"
  168. bad_read    db    "Error reading keystroke file",CR,LF,"$"
  169. too_large    db    "Keystroke file is too large",CR,LF,"$"
  170. installed    db    "Program and keystrokes installed in memory",CR,LF,"$"
  171. reloaded    db    "Keystroke buffer reloaded",CR,LF,"$"
  172.  
  173. first_byte    db    ?        ;For 1st of 2-byte code
  174.  
  175. code_table    dw    "cA",1e01h    ;Control keys
  176.         dw    "cB",3002h
  177.         dw    "cC",2e03h
  178.         dw    "cD",2004h
  179.         dw    "cE",1205h
  180.         dw    "cF",2106h
  181.         dw    "cG",2207h
  182.         dw    "cH",2308h
  183.         dw    "cI",1709h
  184.         dw    "cJ",240ah
  185.         dw    "cK",250bh
  186.         dw    "cL",260ch
  187.         dw    "cM",320dh
  188.         dw    "cN",310eh
  189.         dw    "cO",180fh
  190.         dw    "cP",1910h
  191.         dw    "cQ",1011h
  192.         dw    "cR",1312h
  193.         dw    "cS",1f13h
  194.         dw    "cT",1414h
  195.         dw    "cU",1615h
  196.         dw    "cV",2f16h
  197.         dw    "cW",1117h
  198.         dw    "cX",2d18h
  199.         dw    "cY",1519h
  200.         dw    "cZ",2c1ah
  201.  
  202.         dw    "aA",1e00h    ;Alt keys
  203.         dw    "aB",3000h
  204.         dw    "aC",2e00h
  205.         dw    "aD",2000h
  206.         dw    "aE",1200h
  207.         dw    "aF",2100h
  208.         dw    "aG",2200h
  209.         dw    "aH",2300h
  210.         dw    "aI",1700h
  211.         dw    "aJ",2400h
  212.         dw    "aK",2500h
  213.         dw    "aL",2600h
  214.         dw    "aM",3200h
  215.         dw    "aN",3100h
  216.         dw    "aO",1800h
  217.         dw    "aP",1900h
  218.         dw    "aQ",1000h
  219.         dw    "aR",1300h
  220.         dw    "aS",1f00h
  221.         dw    "aT",1400h
  222.         dw    "aU",1600h
  223.         dw    "aV",2f00h
  224.         dw    "aW",1100h
  225.         dw    "aX",2d00h
  226.         dw    "aY",1500h
  227.         dw    "aZ",2c00h
  228.  
  229.         dw    "F1",3b00h    ;Function keys
  230.         dw    "F2",3c00h
  231.         dw    "F3",3d00h
  232.         dw    "F4",3e00h
  233.         dw    "F5",3f00h
  234.         dw    "F6",4000h
  235.         dw    "F7",4100h
  236.         dw    "F8",4200h
  237.         dw    "F9",4300h
  238.         dw    "Ft",4400h
  239.         dw    "Fe",8500h
  240.         dw    "Fv",8600h
  241.  
  242.         dw    "s1",5400h    ;Shift Function keys
  243.         dw    "s2",5500h
  244.         dw    "s3",5600h
  245.         dw    "s4",5700h
  246.         dw    "s5",5800h
  247.         dw    "s6",5900h
  248.         dw    "s7",5a00h
  249.         dw    "s8",5b00h
  250.         dw    "s9",5c00h
  251.         dw    "st",5d00h
  252.         dw    "se",8700h
  253.         dw    "sv",8800h
  254.  
  255.         dw    "c1",5e00h    ;Control Function keys
  256.         dw    "c2",5f00h
  257.         dw    "c3",6000h
  258.         dw    "c4",6100h
  259.         dw    "c5",6200h
  260.         dw    "c6",6300h
  261.         dw    "c7",6400h
  262.         dw    "c8",6500h
  263.         dw    "c9",6600h
  264.         dw    "ct",6700h
  265.         dw    "ce",8900h
  266.         dw    "cv",8a00h
  267.  
  268.         dw    "a1",6800h    ;Alt function keys
  269.         dw    "a2",6900h
  270.         dw    "a3",6a00h
  271.         dw    "a4",6b00h
  272.         dw    "a5",6c00h
  273.         dw    "a6",6d00h
  274.         dw    "a7",6e00h
  275.         dw    "a8",6f00h
  276.         dw    "a9",7000h
  277.         dw    "at",7100h
  278.         dw    "ae",8b00h
  279.         dw    "av",8c00h
  280.  
  281.         dw    "a!",7800h    ;Alt-numbers
  282.         dw    "a@",7900h
  283.         dw    "a#",7a00h
  284.         dw    "a$",7b00h
  285.         dw    "a%",7c00h
  286.         dw    "a^",7d00h
  287.         dw    "a&",7e00h
  288.         dw    "a*",7f00h
  289.         dw    "a(",8000h
  290.         dw    "a)",8100h
  291.  
  292.         dw    "t1",9800h     ;Tandy 1000 F11 & F12
  293.         dw    "t2",9900h
  294.         dw    "!1",0a200h    ; (shifted)
  295.         dw    "!2",0a300h
  296.         dw    "^1",0ac00h    ; (control)
  297.         dw    "^2",0ad00h
  298.         dw    "~1",0b600h    ; (alt)
  299.         dw    "~2",0b700h
  300.         
  301.         dw    "HM",4700h    ;Home
  302.         dw    "UA",4800h    ;Up-arrow
  303.         dw    "PU",4900h    ;Page Up
  304.         dw    "LA",4b00h    ;Left Arrow
  305.         dw    "RA",4d00h    ;Right Arrow
  306.         dw    "EN",4f00h    ;End
  307.         dw    "DA",5000h    ;Down Arrow
  308.         dw    "PD",5100h    ;Page down
  309.  
  310.         dw    "IN",5200h    ;Insert
  311.         dw    "DL",5300h    ;Delete
  312.         dw    "CR",1c0dh    ;Return/Enter
  313.         dw    "Tb",0f09h    ;Tab
  314.         dw    "BK",0e08h    ;Backspace
  315.         dw    "sb",0f00h    ;Shift-Tab
  316.         dw    "ES",011bh    ;Escape
  317.  
  318.         dw    "P+",4e2bh    ;Pad Plus
  319.         dw    "P-",4a2dh    ;Pad Minus
  320.  
  321.         dw    "ch",7700h    ;Ctrl-home
  322.         dw    "cu",8400h    ;Ctrl-up
  323.         dw    "cl",7300h    ;Ctrl-left
  324.         dw    "cr",7400h    ;Ctrl-right
  325.         dw    "ce",7500h    ;Ctrl-end
  326.         dw    "cd",7600h    ;Ctrl-down
  327.  
  328.         dw    "NL",0000h    ;Null
  329.  
  330. code_len    equ    $-code_table    ;Length of the table
  331.  
  332.  
  333. begin:    lea    dx,hello        ;DS:DX ==> opening message
  334.     mov    ah,9            ;Print the message
  335.     int    21h
  336.     mov    ah,30h            ;Get DOS version
  337.     int    21h
  338.     cmp    al,2            ;At least version 2?
  339.     jae    version_ok        ;Yes -- go
  340.     lea    dx,bad_ver        ;Else report error & leave
  341.     jmp    error
  342. version_ok:
  343.     mov    ax,3508h        ;Get location of Int 08h
  344.     int    21h
  345.     mov    word ptr [old_08],bx    ;Save the address
  346.     mov    word ptr [old_08+2],es    ;  in ES:BX
  347.     mov    ax,3509h        ;Get location of Int 09h
  348.     int    21h
  349.     mov    word ptr [old_09],bx    ;Save the address
  350.     mov    word ptr [old_09+2],es    ;  in ES:BX
  351.     lea    di,new_int09        ;Get code start address in DI
  352.     mov    si,di            ;Copy to SI
  353.     mov    cx,res_code        ;Bytes to compare
  354.     repz    cmpsb            ;Are we already installed?
  355.     jz    read_file        ;Yes -- go
  356.     push    ds            ;Else move ES
  357.     pop    es            ;  to this segme